
#ifndef __API_BRIDGE_H
#define __API_BRIDGE_H

//=== Includes ============================================
#include <wchar.h>
#include <stdarg.h>
#include <assert.h>
#include "memcpy.h"
#import <mach/mach_time.h>
#include "new.h"
#include "CDebug.h"


//#include <memory.h>

//=== Constants ===========================================
//#define ARCHETYPE___effects 0
#define KEY_RIGHT 0
#define KEY_LEFT 1

/*
#define 0		((f32)0)
#define FIXED_POINT( 1.0f ) ((f32)(1 << F32_BITS))
#define FIXED_POINT( 2.0f ) ((f32)(2 << F32_BITS))
#define FIXED_POINT( .5f ) ((f32)( 1 << ( F32_BITS - 1 ))) 
#define ((int32)0x7FFFFFFF) ((f32)0x7FFFFFFF)
#define ((int32)-0x7FFFFFFF) ((f32)-0x7FFFFFFF)
*/

#ifndef TRUE
	#define TRUE	(1)
#endif

#ifndef FALSE
	#define FALSE	(0)
#endif

#define MEDIAPLAYER_MIN_PRIORITY	(-1)
#define MEDIAPLAYER_MAX_PRIORITY	(1000)

#ifndef NULL
	#define NULL	(0)
#endif

#define DBGPRINTF printf

//=== Memory ==============================================
#define MEMCPY( dest, source, n ) MEMORY_COPY( dest, source, n )
#define MEMSET( dest, val, n ) MEMORY_SET( dest, val, n )

//=== Strings =============================================
#define WSTRCMP( a, b ) wcscmp( a, b )
#define WSTRNCOPYN( dest, destSize, source, unUsed ) wcsncpy( dest, source, destSize ) //wcscpy_s( dest, destSize, source )
#define WSTRLEN( a ) ( (int)wcslen( a ) )
#define WSPRINTF swprintf
#define WSSCANF swscanf
#define WSTRCPY	wcscpy

//=== Math ================================================
#ifndef MIN
	#define MIN( a, b ) ( a < b ? a : b )
#endif

#ifndef MAX
	#define MAX( a, b ) ( a > b ? a : b )
#endif

#ifndef ABS
	#define ABS( x ) ( (x) < 0 ? -x : x )
#endif

#define MAX_INT32	( 0x7FFFFFFF )
#define MAX_UINT16 ( 0xFFFF )

//=== Graphics ============================================
#define MAKE_RGB( r, g, b ) (unsigned long)( ( ( 0xFF << 24 ) | ( ( (unsigned long)r & 0xFF ) << 16 ) | ( ( (unsigned long)g & 0xFF ) << 8 ) | ( ( (unsigned long)b & 0xFF ) << 0 ) ) )

//=== Other ===============================================
#define SET_BIT( bits, i ) ( (bits) |= ( 1 << (i) ) )
#define CLEAR_BIT( bits, i ) ( (bits) &= ~( 1 << (i) ) )
#define TEST_BIT( bits, i ) ( (bits) & ( (uint64)1 << (i) ) )

#define SET_MASK(vector,bits)          ( vector |= (bits) )
#define CLEAR_MASK(vector,bits)        ( vector &= (~(bits)) )
#define TEST_MASK(vector,bits)         ( (vector & (bits)) == bits )

#define SAFE_DELETE( p )       if( p ) { delete (p); (p) = NULL; }
#define SAFE_DELETE_ARRAY( p ) if( p ) { delete [] (p); (p) = NULL; }
#define RESGEN_GET_REAL_ID( id ) ( (id) & 0x7FFF )

#define SHIFT_LEFT(vector,bits)		   ( (vector) <<= (bits) )
#define SHIFT_RIGHT(vector,bits)	   ( (vector) >>= (bits) )

#define SET_ARRAY_BIT(vector,bit)      ( vector[(bit) >> 3] |= ( 1 << ( (bit) & 0x07 ) ) )
#define CLEAR_ARRAY_BIT(vector,bit)    ( vector[(bit) >> 3] &= ~( 1 << (bit) & 0x07 ) )
#define TEST_ARRAY_BIT(vector,bit)     ( ( vector[(bit) >> 3] & ( 1 << ( (bit) & 0x07 ) ) ) != 0 )

#define ASSERT( x ) assert( x )
#define DDDASSERT(x,y)
#define CT_ASSERT( test )
#define API_ASSERT(x) assert(x)
#define	API_DDDASSERT(x,y)
#define VERIFY(x)                  do { x; } while( false )
#define ERROR( msg )

#define GETTIMEMS( ) (timeMS())
#define EXIT_APP( ) int jesse____

#define DDD( x )	CDebug::LogMessage x

inline unsigned timeMS()
{
	uint64_t        absolute;
	
	static double conversion = 0.;
	
	if( conversion == 0. )
	{
		mach_timebase_info_data_t info;
		mach_timebase_info( &info );
		conversion = (double)info.numer / (double)info.denom;
	}
	
	// Start the clock.
	absolute = mach_absolute_time() * conversion;
	
	return (unsigned)( absolute / 1000000 );
}


enum no_ctor_modify { _no_ctor_modify_value = 0 };	// For explicit contructors that do not modify member variables  
#define NO_CTOR_MODIFY  (_no_ctor_modify_value)		// Use this to explicitly select contructors that do not modify member variables  

typedef struct 
{
   int16    x,y;
   int16   dx, dy;
} AEERect;

//=== Retarded legacy shit ================================
enum eRC
{
	// generic return codes
	RC_SUCCESS                  = 0x00,
	RC_FAILURE                  = 0x01,
	RC_OUT_OF_MEMORY            = 0x02,
	RC_BAD_PARAMS               = 0x03,	
	RC_INVALID_STATE            = 0x04,	
	RC_OUT_OF_BOUNDS            = 0x05,
	RC_NOT_FOUND                = 0x06,
	RC_EXISTS                   = 0x07,
	RC_EOF                      = 0x08,

	// application-specific return codes
	RC_APPLICATION              = 0xA0	
};

#define BLOCK_START(name)                       \
	do {               

#define BLOCK_END(name)                         \
	__tryLabel##name##__:                       \
		break;                                  \
	} while( 0 )

#define BLOCK_CHECK(name,test)                  \
		do {                                    \
			if( !(test) )                       \
				BLOCK_BREAK( name );            \
		} while( 0 )

#define BLOCK_CHECKRC(name,rc)                  \
	BLOCK_CHECK( name, ( (rc) == RC_SUCCESS ) )

#define BLOCK_BREAK(name)                       \
		goto __tryLabel##name##__


	#define PROFILER_HANDLE									void*
	#define PROFILER_HANDLE_INVALID							NULL 
	#define DECLARE_PROFILE_HANDLE( handle )				int* handle	
	#define INIT_PROFILE_HANDLE( handle )
	#define DECLARE_PROFILE_ZONE( handle, name, color )		
	#define ENTER_PROFILE_ZONE( handle )					
	#define EXIT_PROFILE_ZONE( handle )				
	
#endif // __API_BRIDGE_H